package ch.cryptobox.ui;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import ch.cryptobox.MessageBus;
import ch.cryptobox.filehandles.FileHandleI;
import ch.cryptobox.serivces.RemoteFileService;

public class NFSNavigator implements Runnable {
	private final RemoteFileService synchService;
	private FileHandleI current;
	private final String localMountPoint;

	public NFSNavigator(final RemoteFileService synchService, final String localMountPoint) {
		this.synchService = synchService;
		current = synchService.getRootHandle();
		this.localMountPoint = localMountPoint;
	}

	@Override
	public void run() {
		System.out.print(current + ">");

		final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		try {
			String line = reader.readLine().trim();

			while(!"quit".equals(line)) {

				if("ls".equals(line)) {
					final ArrayList<FileHandleI> content = current.getFiles();
					
					
					for(final FileHandleI c: content) {
						System.out.println(c);
					}

				} else if(line.startsWith("cd")) {
					final String[] args = line.split(" ");
					if(args.length < 2) {
						current = synchService.getRootHandle();
					} else {
						final FileHandleI temp = current.getDirectory(args[args.length-1]);
						if(temp == null || !temp.isDirectory()) {
							System.out.println("Directory not found");
						} else {
							current = temp;
						}
					}


				} else if("pwd".equals(line)) {
					System.out.println(current.getPath());
				} else if(line.startsWith("cat")) {
					final String[] args = line.split(" ");
					if(args.length < 2) { 
						System.out.println("Usage cat: cat <filename>");
					} else {
						final String fileName = args[args.length-1];

						final FileHandleI temp = current.getFile(fileName);

						if(temp == null || temp.isDirectory()) {
							System.out.println("File " + fileName + " not found");

						} else {
							final byte[] data = temp.download();
							if(null == data) {
								System.out.println("Download failed for " + fileName);
							} else {
								System.out.println(new String(data));
							}
						}
					}
				} else if(line.startsWith("restore") ) {
					final String[] args = line.split(" ");
					if(args.length < 2) { 
						System.out.println("Usage restore: restore <filename>");
					} else {
						final String fileName = args[args.length-1];
						
						
						FileHandleI  temp;
						if(".".equals(fileName)) {
							temp = current;
						} else {	
							temp = current.getFile(fileName);
						}
						if(temp == null) {
							System.out.println("File " + fileName + " not found");

						} else {
							if(!restore(temp) ) {
								System.out.println("Restore failed for " + fileName);
							} else {
								System.out.println("Restore successful");
							}
						}
					}
				}

				else {
					System.out.println("commands:\n ls\ncd\npwd\ncat\nrestore");

				}


				System.out.print(current + " > ");
				line = reader.readLine();
			}


			reader.close();
		} catch (final Exception e) {
			e.printStackTrace();
		}
		

	}

	public boolean restore(final FileHandleI file) {
		if(file.isDirectory()) {
			
			boolean success = true;
			final File localFile = new File(localMountPoint + file.getPath());
			MessageBus.getInstance().addToBeIgnoredOnce(localFile.getPath());
			
			localFile.mkdirs();
			
			final ArrayList<FileHandleI> files = file.getFiles();
			for(final FileHandleI f : files) {
				success &= restore(f);
			}
			
			System.out.println("RESTORED Directory: " + file.getName());
			return success;
		}
		
		final byte[] data = file.download();

		if(null == data) {
			return false;
		} else {
			try {
				//System.out.println(localMountPoint + file.getPath());
				final File localFile = new File(localMountPoint + file.getPath());
				final File parent = new File(localFile.getParent());
				
				if(!parent.exists()) {
					MessageBus.getInstance().addToBeIgnoredOnce(parent.getPath());
					parent.mkdirs();
				} else {
					MessageBus.getInstance().addToBeIgnoredOnce(localFile.getPath());
				}

				final FileOutputStream writer = new FileOutputStream(localFile);
				writer.write(data);
				writer.close();
			} catch (final IOException e) {

				e.printStackTrace();
				return false;
			}

			System.out.println("RESTORED File: " + file.getName());
			return true;
		}
	}

}
